<?php
namespace app\houtai\controller\user\redis;
use app\houtai\controller\BaseController;
use think\Db;
use RuntimeException;
use think\db\Expression;
use org\GoApi\UserCtrl;

class ControlController extends BaseController {
  
  const OPERATES = [
    1 => '增加',
    2 => '修改',
    4 => '删除',
    // 8 => '自动删除',  // 过期删除
  ];
  
  /**
   *  @brief  : 读redis用户控制列表
   *  @return : page
   *  @details:
   */
  public function indexAction() {
    $rows   = [];
    $conds  = [];
    $order  = [];
    $search = $this->request->param('search/s', '', 'trim');
    $CHANNELS = $this->GetAdminChannel();
    $total = 0;
    //////////////////////////////////////////////////////////////////////////////////////
    $time = $this->request->param('time/s', '', 'trim,YmdHis2Unix');
    $time = YmdHis2Unix(date('Y-m-d 00:00:00', $time > 0 ? $time : time()));
    $channel = $this->request->param('channel/d', -1);
    if ($channel > 0 && array_key_exists($channel, $CHANNELS)) {
      $conds['b.Channel'][] = ['IN', array_keys($CHANNELS)];
      $conds['b.Channel'][] = ['EQ', $channel];
    } else {
      $conds['b.Channel'] = ['IN', array_keys($CHANNELS)];
    }
    //////////////////////////////////////////////////////////////////////////////////////
    if ($search > 0) { // 查询指定用户
      $eax = UserCtrl::Read($search);
      if (!empty($eax)) {
        $rows[] = $eax;
      }
    } else {
      $eax = UserCtrl::Page($channel, $this->pageCurrent, $this->pageSize);
      $eax = $eax['PageJson'];
      // $eax['data'] = json_decode($eax['data'],true);
      if (!empty($eax['data'])) {
        $rows = $eax['data'];
        $total = $eax['Total'];
      }
    }
    //////////////////////////////////////////////////////////////////////////////////////
    $listRd = [];
    $listDb = [];
    if (!empty($rows)) {
      foreach($rows as $eax) {
        $eax = json_decode($eax,true);
        $listRd[$eax['GameID']] = $eax;
      }
      //////////////////////////////////////////////////////////////////////////////////////
      $TMS = [
        [$time - 0 * 24 * 60 * 60, $time + 1 * 24 * 60 * 60], // day0
        [$time - 1 * 24 * 60 * 60, $time - 0 * 24 * 60 * 60],
        [$time - 2 * 24 * 60 * 60, $time - 1 * 24 * 60 * 60],
        [$time - 3 * 24 * 60 * 60, $time - 2 * 24 * 60 * 60],
        [$time - 4 * 24 * 60 * 60, $time - 3 * 24 * 60 * 60],
        [$time - 5 * 24 * 60 * 60, $time - 4 * 24 * 60 * 60],
        [$time - 6 * 24 * 60 * 60, $time - 5 * 24 * 60 * 60], // day6
        [$time - 6 * 24 * 60 * 60, $time + 1 * 24 * 60 * 60], // day7 合计
      ];
      $arr = [];
      foreach($TMS as $k=>$v) {
        $key = sprintf("( SELECT ISNULL(SUM (e.lScore), 0) FROM CYRecordDB.dbo.RecordGameDataUserRecord e WHERE e.UserID = b.UserID AND e.CreateTime BETWEEN '%s' AND '%s' )",
          YmdHis($v[0]), YmdHis($v[1])
        );
        $arr[$key] = "day{$k}";
      }
      //////////////////////////////////////////////////////////////////////////////////////
      $orderMap = [
        'B' => 'Channel',
        'C' => 'RegisterDate',
        'D' => 'GameID',
        'I' => 'day6',
        'J' => 'day5',
        'K' => 'day4',
        'L' => 'day3',
        'M' => 'day2',
        'N' => 'day1',
        'O' => 'day0',
        'P' => 'day7',
        'Q' => 'days',
      ];
      $this->orderField = array_key_exists($this->orderField, $orderMap) ? $this->orderField : 'P';
      $order[$orderMap[$this->orderField]] = $this->orderDirection;
      //////////////////////////////////////////////////////////////////////////////////////
      $listDb = table('CYBasicDB.dbo.AccountsInfo b', 'rydb.basic')->field(array_merge([
        'b.UserID', 'b.GameID', 'b.NickName', 'b.Sex', 'b.AccountImgUrl', 'b.Channel',
        'b.AccountsType', 'b.Accounts', 'b.Compellation', 'b.PassPortID', 'b.RegisterMobile',
        'b.RegisterDate', 'b.RegisterIP', 'b.LastLogonDate'=>'GameLogonTimes', 'b.LastLogonDate', 'b.LastLogonIP',
        '( SELECT ISNULL(SUM (e.lScore), 0) FROM CYRecordDB.dbo.RecordGameDataUserRecord e WHERE e.UserID = b.UserID )' => 'days',
      ], $arr))
      ->where('b.GameID', 'IN', array_keys($listRd))
      ->where($conds)
      ->order($order)
      ->select();

      $arr = [];
      if (!empty($listDb)) {
        foreach($listDb as $eax) {
          $arr[$eax['GameID']] = $eax;
        }
      }
      $listDb = $arr;
    }
    $path  = $this->request->baseUrl();
    $pager = new \org\dtcms($rows, $this->pageSize, $this->pageCurrent, $total, false, ['path'=>$path]);
    //////////////////////////////////////////////////////////////////////////////////////
    return $this->fetch('', [
      'search'  => $search,
      'channel' => $channel,
      'time'    => $time,
      'CHANNELS'=> $CHANNELS,
      'listRd'  => $listRd,
      'listDb'  => $listDb,
      'SEXARR'  => [0 => '未知', 1 => '男性', 2 => '女性'],
      'pager'   => $pager,
    ]);
  }
  /**
   *  @brief  : 读写redis用户控制参数
   *  @return : page|JSON
   *  @details:
   */
  public function detailAction() {
    $GameID = $this->request->param('GameID/d', 0);
    if ($this->request->isGet()) { // `读取/新增`模板
      $conf = $GameID > 0 ? UserCtrl::Read($GameID) : [];
      return $this->fetch('', ['GameID' => $GameID, 'Conf' => $conf]);
    } else {
      ////////////////////////////////////
      if ($GameID <= 0) {
        return result([], 10, 'GameID不能为负数');
      }
      $Range = $this->request->param('Range/d', 0);
      $Rate  = $this->request->param('Rate/d', 0);
      if ($Rate < 0 || $Rate > 100) {
        return result([], 11, '几率为正整数[0~100]');
      }
      ////////////////////////////////////
      $user = table('AccountsInfo', 'rydb.basic')->field(['GameID', 'Channel','NickName'])->where('GameID', $GameID)->find();
      if (empty($user)) {
        return result([], 12, 'GameID不存在');
      }
      ////////////////////////////////////
      $NowSocre = table('CYRecordDB.dbo.RecordGameDataUserRecord a', 'rydb.record')
                ->join('CYBasicDB.dbo.AccountsInfo b', 'b.UserID = a.UserID', 'LEFT')
                ->where(['b.GameID' => $GameID])
                ->whereTime('a.CreateTime', 'today')
                ->sum('a.lScore');
      ////////////////////////////////////
      $rule = UserCtrl::Read($GameID);
      $eax = UserCtrl::Save($GameID, $Range, $Rate, $NowSocre, $user['Channel'],$user['NickName']);
      if ($eax == 0) { // 执行成功
        $eax = ['Range' => $Range, 'Rate' => $Rate];
        if (empty($rule)) { // 添加
          $eax['Score'] = $NowSocre;
          $eax = self::clog(1, $GameID, $eax);
        } else { // 修改
          if ($Range != $rule['Range'] || $Rate != $rule['Rate']) { // 发生变动
            $eax['Score'] = $rule['Score'];
            $eax = self::clog(2, $GameID, $eax);
          }
        }
      }
      return result([], 0);
    }
  }
  /**
   *  @brief  : 删除操作
   *  @return : JSON
   *  @details:
   */
  public function deloneAction() {
    $GameID = $this->request->param('GameID/d', 0);
    if ($GameID <= 0) {
      return result([], 10, 'GameID不能为负数');
    }
    $rule = $GameID > 0 ? UserCtrl::Read($GameID) : [];
    if (empty($rule)) {
      return result([], 11, '规则不存在');
    }
    $eax = UserCtrl::Remove($GameID);
    if ($eax == 0) {
      self::clog(4, $GameID, $rule);
    }
    return result([], $eax);
  }
  /**
   *  @brief  : 记录操作日志
   *  @param [in] $operate : 记录类型`OPERATES`
   *  @param [in] $GameID  : 
   *  @return : none
   *  @details: // 601093// 基础分数Range/当前分数Score/几率Rate
   */
  protected static function clog($operate, $GameID, $data = []) {
    
    if (!array_key_exists($operate, self::OPERATES)) {
      throw new RuntimeException('操作类型未定义');
    }
    
    $data = array_merge([
      'Score' => 0, 'Range' => 0, 'Rate' => 0,
    ], $data);
    
    $UserID = table('CYBasicDB.dbo.AccountsInfo', 'rydb.basic')->where('GameID', $GameID)->value('UserID');
    if ($UserID <= 0) {
      throw new RuntimeException('用户不存在');
    }
    $row = [
      'UserID'  => $UserID,
      'Type'    => $operate,
      'Remark'  => sprintf('基础分数=%d, 当前几率=%d, 当前分数=%d',
        $data['Range'],
        $data['Rate'],
        $data['Score']
      ),
      'CollectTime' => new Expression('GETDATE()'),
    ];
    table('CYWebSMSDB.dbo.RedisControlLog', 'rydb.websms')->insert($row);
  }
  /**
   *  @brief  : redis控制操作日志
   *  @return : page
   *  @details: 
   */
  public function logAction() {
    $conds = ['a.Status' => 1];
    $order = [];
    $CHANNELS = $this->GetAdminChannel();
    //////////////////////////////////////////////////////////////////////////////////////
    $search = $this->request->param('search/s', '', 'trim');
    if (!empty($search)) {
      if (is_numeric($search)) {
        $search = $this->request->param('search/d', 0);
        if ($search > 0) {
          $conds['a.UserID|b.GameID'] = $search;
        }
      } else {
        $conds['b.NickName'] = ['LIKE', "%{$search}%"];
      }
    }
    //////////////////////////////////////////
    $channel = $this->request->param('channel/d', -1);
    if ($channel > 0 && array_key_exists($channel, $CHANNELS)) {
      $conds['b.Channel'][] = ['IN', array_keys($CHANNELS)];
      $conds['b.Channel'][] = ['EQ', $channel];
    } else {
      $conds['b.Channel'] = ['IN', array_keys($CHANNELS)];
    }
    //////////////////////////////////////////
    $operate = $this->request->param('operate/d', -1);
    if ($operate > 0 && array_key_exists($operate, self::OPERATES)) {
      $conds['a.Type'] = $operate;
    }
    //////////////////////////////////////////
    $time1 = $this->request->param('time1/d', 0, 'trim,YmdHis2Unix');
    $time2 = $this->request->param('time2/d', 0, 'trim,YmdHis2Unix');
    $timea = YmdHis($time1);
    $timeb = YmdHis($time2);
    if ($time1 > 0) {
      if ($time2 > 0) {
        if ($time1 <= $time2) {
          $conds['a.CollectTime'] = ['BETWEEN TIME', [$timea, $timeb]];
        } else {
          $conds['a.CollectTime'] = ['>= TIME', $timea];
        }
      } else {
        $conds['a.CollectTime'] = ['>= TIME', $timea];
      }
    } else {
      if ($time2 > 0) {
        $conds['a.CollectTime'] = ['<= TIME', $timeb];
      }
    }
    //////////////////////////////////////////
    $orderMap = [
      'A' => 'ID',
      'B' => 'Channel',
      'C' => 'GameID',
      'D' => 'Type',
      'E' => 'CollectTime',
      'F' => 'Remark',
    ];
    $this->orderField = array_key_exists($this->orderField, $orderMap) ? $this->orderField : 'F';
    $order[$orderMap[$this->orderField]] = $this->orderDirection;
    //////////////////////////////////////////
    $list = table('CYWebSMSDB.dbo.RedisControlLog a', 'rydb.websms')->field([
      'a.ID', 'a.UserID', 'a.Type', 'a.CollectTime', 'a.Remark', 'b.GameID', 'b.SpreaderID',
      'b.Sex', 'b.Channel', 'b.AccountImgUrl', 'b.Accounts', 'b.Compellation', 'b.PassPortID',
      'b.RegisterMobile', 'b.RegisterDate', 'b.RegisterIP', 'b.GameLogonCount', 'b.LastLogonDate',
      'b.LastLogonIP', 'b.AccountsType', 'b.NickName'
    ])
    ->join('CYBasicDB.dbo.AccountsInfo b', 'b.UserID = a.UserID', 'LEFT')
    ->where($conds)->order($order)->paginate();
    //////////////////////////////////////////////////////////////////////////////////////
    return $this->fetch('', [
      'CHANNELS'  => $CHANNELS,
      'OPERATES'  => self::OPERATES,
      'operate'   => $operate,
      'channel'   => $channel,
      'search'    => $search,
      'list'      => $list,
      'time1'     => '',
      'time2'     => '',
    ]);
  }
  /**
   *  @brief  : 删除全部规则
   *  @return : JSON
   *  @details: 
   */
  public function delallAction() {
    $channel = $this->request->param('channel/d', -1);
    $retn = UserCtrl::RemoveALL($channel);
    return result([], 0);
  }
  /**
   *  @brief  : 清除所有操作日志
   *  @return : JSON
   *  @details:
   */
  public function dellogAction() {
    $eax = table('CYWebSMSDB.dbo.RedisControlLog', 'rydb.websms')->where(['Status' => 1])->setField('Status', 0);
    $eax = table('CYWebSMSDB.dbo.RedisControlLog', 'rydb.websms')->where('DATEDIFF(dd, CollectTime, GETDATE())>30')->delete();
    return result([], 0);
  }
}
